﻿using System.Collections.Generic;
using UnityEngine;

namespace Framework
{
    public static class FrameworkSettings
    {
        public static readonly string FrameworkDirName = "framework";
        public static readonly string FrameworkRootDir = Application.dataPath + "/" + FrameworkDirName;
        public static readonly string FrameworkEditorRootDir = FrameworkRootDir + "/Editor";
        public static readonly string FrameworkLuaRootDir = FrameworkRootDir + "/Scripts/Lua";

        public static readonly bool UseSBP = true;

        #region tolua 相关的路径设置
        public static readonly string FrameworkToLuaRootDir = FrameworkRootDir + "/ToLua";
        public static readonly string FrameworkToLuaBaseTypeDir = FrameworkToLuaRootDir + "/BaseType";
        public static readonly string FrameworkToLuaBaseLuaDir = FrameworkToLuaRootDir + "/Lua";
        public static readonly string FrameworkToLuaInjectionDir = FrameworkToLuaRootDir + "/Injection";
        #endregion

        #region
        public static readonly string ProjDirName = "Proj";
        public static readonly string ProjRootDir = Application.dataPath + "/" + ProjDirName;
        public static readonly string ProjcSharpRootDir = ProjRootDir + "/Scripts/CSharp";
        public static readonly string ProjLuaRootDir = ProjRootDir + "/Scripts/Lua";
        public static readonly string ProjToLuaGenerateRootDir = ProjRootDir + "/Scripts/ToLua/Generate";
        public static readonly string ProjEditorRootDir = ProjRootDir + "/Editor";

        #endregion

        #region 平台相关判定
        public static readonly string Android = "Android";
        public static readonly string IOS = "iOS";
        public static readonly string Windows = "Windows";
        public static readonly string MacOSX = "Mac";
        public const int AndroidPlayer = 0;
        public const int IOSPlayer = 1;
        public const int WindowsPlayer = 2;
        public const int OSXPlayer = 3;

        private static readonly Dictionary<string, int> PlatformNameId = new Dictionary<string, int>
        {
            {Windows, WindowsPlayer},
            {MacOSX, OSXPlayer},
            {Android, AndroidPlayer},
            {IOS, IOSPlayer},
        };

        private static readonly Dictionary<int, string> PlatformIdName = new Dictionary<int, string>
        {
            {AndroidPlayer, Android},
            {IOSPlayer, IOS},
            {WindowsPlayer, Windows},
            {OSXPlayer, MacOSX},
        };

        public static string PlatformIdToName(int platformId)
        {
            string name;
            if (PlatformIdName.TryGetValue(platformId, out name))
            {
                return name;
            }
            Logger.LogError("FrameworkSettings.PlatformIdToName, platformId = " + platformId + " is not defined!");
            return string.Empty;
        }

        public static int NameToPlatformId(string name)
        {
            int id;
            if (PlatformNameId.TryGetValue(name, out id))
            {
                return id;
            }
            Logger.LogError("FrameworkSettings.NameToPlatformId, name = " + name + " is not defined!");
            return 0;
        }

        /// <summary>
        /// 当前平台名字
        /// </summary>
        public static string CurPlatformName
        {
            get
            {
#if (UNITY_STANDALONE_WIN || UNITY_EDITOR_WIN)
                return Windows;
#elif (UNITY_STANDALONE_OSX || UNITY_EDITOR_OSX)
                return MacOSX;
#elif UNITY_ANDROID
                return Android;
#elif UNITY_IOS
                return IOS;
#endif
            }
        }
        /// <summary>
        /// 当前平台,lua中可以用这个来判定平台
        /// </summary>
        public static int CurPlatform
        {
            get
            {
#if (UNITY_STANDALONE_WIN || UNITY_EDITOR_WIN)
                return WindowsPlayer;
#elif (UNITY_STANDALONE_OSX || UNITY_EDITOR_OSX)
                return OSXPlayer;
#elif UNITY_ANDROID
                return AndroidPlayer;
#elif UNITY_IOS
                return IOSPlayer;
#endif
            }
        }

        /// <summary>
        /// 是否是64位平台
        /// </summary>
        public static bool Is64Bit
        {
            get
            {
#if (UNITY_STANDALONE_WIN || UNITY_EDITOR_WIN)
                return true;
#elif (UNITY_STANDALONE_OSX || UNITY_EDITOR_OSX)
                return true;
#elif UNITY_ANDROID
                return (System.IntPtr.Size == 8);
#elif UNITY_IOS
                return (System.IntPtr.Size == 8);
#endif
            }
        }
        /// <summary>
        /// 当前是否是编辑器环境
        /// </summary>
        public static bool IsEditor
        {
            get
            {
#if UNITY_EDITOR
                return true;
#else
                return false;
#endif
            }
        }

        public static bool IsStandalonePlayer()
        {
            return (CurPlatform == OSXPlayer || CurPlatform == WindowsPlayer);
        }

        public static bool IsMobilePlayer()
        {
            return (CurPlatform == AndroidPlayer || CurPlatform == IOSPlayer);
        }

        public static bool IsAndroidPlayer()
        {
            return CurPlatform == AndroidPlayer;
        }
        public static bool IsIOSPlayer()
        {
            return CurPlatform == IOSPlayer;
        }
        #endregion

        #region 所有读写目录路径设置
        /// <summary>
        /// 编辑器中的资源库名字
        /// </summary>
        public static readonly string ResourcesLibName = "Res";

        /// <summary>
        /// 外部构建之后的资源库名字
        /// </summary>
        public static readonly string OutResLibName = "ResLib";
        /// <summary>
        /// ab存放的根目录
        /// </summary>
        public static readonly string AssetBundleInPackage = "bundles";

        /// <summary>
        /// lua字节码文件夹名字
        /// </summary>
        public static readonly string OutLuaBytesDirName = "luabytes";
        
        public static string GetAbRootDir(int platId)
        {
            var platformName = PlatformIdToName(platId);
            return Application.dataPath.Replace("Assets", OutResLibName + "/" + platformName + "/" + "AssetBundles");
        }
        
        /// <summary>
        /// 包体只读目录路径
        /// </summary>
        public static string StreamingAssetsPath
        {
            get
            {
#if UNITY_EDITOR
                return Application.dataPath.Replace("Assets", OutResLibName);
#elif (UNITY_STANDALONE_WIN || UNITY_STANDALONE_OSX)
                return Application.streamingAssetsPath;
#elif UNITY_IOS
                return Application.dataPath + "/Raw";
#elif UNITY_ANDROID
                return Application.dataPath + "!/assets";
#endif
            }
        }

        /// <summary>
        /// 随包体文件的前缀
        /// </summary>
        public static string StreamingFilePrefix
        {
            get
            {
#if UNITY_EDITOR
                return @"file://";
#elif (UNITY_STANDALONE_WIN || UNITY_STANDALONE_OSX)
                return @"file://";
#elif UNITY_IOS
                return "file://";
#elif UNITY_ANDROID
                return "jar:file://";
#endif
            }
        }

        /// <summary>
        /// 可读写的外部目录的文件前缀
        /// </summary>
        public static string PersistentFilePrefix
        {
            get
            {
#if UNITY_EDITOR
                return @"file://";
#elif (UNITY_STANDALONE_WIN || UNITY_STANDALONE_OSX)
                return @"file://";
#elif UNITY_IOS
                return "file://";
#elif UNITY_ANDROID
                return "file://";
#endif
            }
        }

        /// <summary>
        /// 包体资源根目录
        /// </summary>
        public static readonly string StreamingResRootDir = StreamingAssetsPath + "/" + CurPlatformName;
        /// <summary>
        /// 可读写资源根目录
        /// </summary>
        public static readonly string PersistentResRootDir =
#if !UNITY_STANDALONE || UNITY_EDITOR
        Application.persistentDataPath + "/" + OutResLibName + "/" + CurPlatformName;
#else
        StreamingAssetsPath + "/PersistentRoot";
#endif
        /// <summary>
        /// 可读写资源目录，临时目录1
        /// </summary>
        public static readonly string PersistentResTmepDir1 = PersistentResRootDir + "/_tmp1";
        /// <summary>
        /// 可读写资源目录，临时目录2
        /// </summary>
        public static readonly string PersistentResTmepDir2 = PersistentResRootDir + "/_tmp2";
        public static readonly string PersistentResTmepDir3 = PersistentResRootDir + "/_tmp3";
        /// <summary>
        /// 资源库相对路径
        /// </summary>
        public static readonly string AssetRootDir = "Assets/" + FrameworkSettings.ResourcesLibName;

        /// <summary>
        /// 编辑器用
        /// </summary>
        public static readonly string FullAssetRootDir = Application.dataPath + "/" + FrameworkSettings.ResourcesLibName;

        /// <summary>
        /// 真机下资源库相对路径
        /// </summary>
        /// <returns></returns>
        public static readonly string AssetRootInBundle = AssetRootDir;

        #endregion

        #region 资源相关

        /// <summary>
        /// 自定义数据字节码的后缀
        /// </summary>
        public static readonly string DataExt = ".dat";
        /// <summary>
        /// lua字节码的后缀
        /// </summary>
        public static readonly string LuaCodeExt = ".dat";
        /// <summary>
        /// ab的后缀名
        /// </summary>
        public static readonly string AssetBundleExt = ".dat";
        /// <summary>
        /// 预设体的后缀
        /// </summary>
        public static readonly string PrefabBundleExt = ".prefab.dat";

        /// <summary>
        /// 获取ab系统中，某个资源的路径
        /// </summary>
        /// <param name="assetPath"></param>
        /// <returns></returns>
        public static string GetAssetNameInBundle(string assetPath)
        {
            return AssetRootInBundle + "/" + assetPath;
        }

        /// <summary>
        /// 获取资源的全路径 有加http协议头
        /// release包：
        /// 1.如果有热更新过，则取外部可读写目录的
        /// 2.如果没有热更新过，则取包体内部的
        /// debug包：
        /// 优先读取外部目录的，外部不存在，则使用包内的
        /// </summary>
        /// <param name="assetPath">资源相对路径</param> 
        /// <returns>资源全路径</returns>
        public static string GetAssetFullPathForWWW(string assetPath)
        {
            // if (ResMgr.Instance.IsFromEditorDir)
            if (true)
            {
                return FrameworkSettings.GetAbRootDir(FrameworkSettings.AndroidPlayer) + "/" + assetPath;
            }
            bool isUpdated = FileHelper.IsFileExists(PersistentResRootDir + "/" + assetPath);
            if (isUpdated)
            {
                // Logger.Log("FrameworkSettings.GetAssetFullPathForWWW assetPath = " + assetPath + " isUpdated = " + isUpdated);
                return GetPersistResPathWWW(assetPath);
            }
            else
            {
                return GetStreamingResPathForWWW(assetPath);
            }
        }

        public static string GetAssetFullConfigPath(string assetPath, int platId = AndroidPlayer)
        {
            var platformName = PlatformIdToName(platId);
            return Application.dataPath.Replace("Assets", OutResLibName + "/" + platformName + "/configs/" + assetPath);
        }
        
        /// <summary>
        /// 获取ab资源的文件路径
        /// 非Android包：
        /// 1.如果有热更新过，则取外部可读写目录的
        /// 2.如果没有热更新过，则取包体内部的
        /// Android包：
        /// 读取外部目录的
        /// </summary>
        /// <param name="assetPath"></param>
        /// <returns></returns>
        public static string GetAbAssetFilePath(string assetPath)
        {
            if(IsAndroidPlayer())
            {
                return GetPersistResPath(assetPath, false);
            }
            var isUpdated = FileHelper.IsFileExists(PersistentResRootDir + "/" + assetPath);
            if (isUpdated)
            {
                //Logger.Log("FrameworkSettings.GetAbAssetFilePath assetPath = " + assetPath + " isUpdated = " + isUpdated);
                return GetPersistResPath(assetPath, false);
            }
            else
            {
                return GetStreamingResPath(assetPath, false);
            }
        }

        /// <summary>
        /// 获取资源的文件路径
        /// 非Android包：
        /// 1.如果有热更新过，则取外部可读写目录的
        /// 2.如果没有热更新过，则取包体内部的
        public static string GetAssetFilePath(string assetPath)
        {
            var isUpdated = FileHelper.IsFileExists(PersistentResRootDir + "/" + assetPath);
            if (isUpdated)
            {
                //Logger.Log("FrameworkSettings.GetAbAssetFilePath assetPath = " + assetPath + " isUpdated = " + isUpdated);
                return GetPersistResPath(assetPath, false);
            }
            else
            {
                return GetStreamingResPath(assetPath, false);
            }
        }


        //获取移动平台可读写目录lua文件，主要用于移动端调试
        public static string GetPersistentDataLuaPath(string luaFileName)
        {
            return string.Format("{0}/lua/{1}.lua", Application.persistentDataPath, luaFileName);
        }

        internal static string GetPersistResPathWWW(string relativePath)
        {
            return GetPersistResPath(relativePath, true);
        }

        internal static string GetStreamingResPathForWWW(string relativePath)
        {
            return GetStreamingResPath(relativePath, true);
        }

        private static string GetPersistResPath(string relativePath, bool useHttpHead)
        {
            return (useHttpHead ? PersistentFilePrefix : "") + PersistentResRootDir + "/" + relativePath;
        }

        private static string GetStreamingResPath(string relativePath, bool useHttpHead)
        {
            return (useHttpHead ? StreamingFilePrefix : "") + StreamingResRootDir + "/" + relativePath;
        }

        public static string GetEditorResPath(string relativePath)
        {
            return AssetRootDir + "/" + relativePath;
        }
        #endregion
    }
}

